/**
 * @file binary_tree.c
 * File implementing a generic BinaryTree data structure
 * @author Denis Ollier
 * @ingroup BinaryTree
 */

#include <binary_tree.h>
#include <stdlib.h>

/**
 *
 * @param node
 * @retval 0
 * @retval 1
 */
static unsigned int binary_tree_create_node (struct binary_node** node)
{
	*node = (struct binary_node*) malloc(sizeof(struct binary_node));
	if ((*node)->left_child != NULL)
	{
		(*node)->left_child->element = NULL;
		(*node)->left_child->left_child = NULL;
		(*node)->left_child->right_child = NULL;
		return 1;
	}
	return 0;
}

/**
 *
 * @param tree
 * @param node
 */
static void binary_tree_destroy_node(binary_tree tree, struct binary_node* node)
{
	tree->element_destructor(node->element);
	free(node);
}

unsigned int binary_tree_insert_element(binary_tree tree, const void* element)
{
	struct binary_node* it;
	unsigned int located;
	int comp_result;

	if (tree->root == NULL)
	{
		return binary_tree_create_node(&(tree->root));
	}
	else
	{
		it = tree->root;
		located = 0;

		while (!located)
		{
			comp_result = tree->elements_comparator(element, it->element);
			if (it->left_child != NULL && comp_result == -1)
			{
				it = it->left_child;
			}
			else if (it->right_child != NULL && comp_result >= 0)
			{
				it = it->right_child;
			}
			else
			{
				located = 1;
			}
		}

		if (comp_result == -1)
		{
			return binary_tree_create_node(&(it->left_child));
		}
		return binary_tree_create_node(&(it->right_child));
	}
}

binary_tree binary_tree_new(comparator_t elements_comparator, destructor_t element_destructor)
{
	binary_tree new_binary_tree;

	new_binary_tree = (binary_tree) malloc(sizeof(struct binary_tree));
	new_binary_tree->root = NULL;
	new_binary_tree->elements_comparator = elements_comparator;
	new_binary_tree->element_destructor = element_destructor;

	return new_binary_tree;
}

unsigned int binary_tree_remove_element(binary_tree tree, const void* element)
{
}

void binary_tree_set_comparator(binary_tree tree, comparator_t elements_comparator)
{
	tree->elements_comparator = elements_comparator;
}

void binary_tree_set_destructor(binary_tree tree, destructor_t element_destructor)
{
	tree->element_destructor = element_destructor;
}
